home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / find.cc < prev    next >
C/C++ Source or Header  |  1996-11-03  |  4KB  |  202 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include "defun-dld.h"
  28. #include "error.h"
  29. #include "gripes.h"
  30. #include "help.h"
  31. #include "oct-obj.h"
  32.  
  33. static octave_value_list
  34. find_to_fortran_idx (const ColumnVector i_idx, const ColumnVector j_idx,
  35.              const octave_value& val, int nr, int nargout)
  36. {
  37.   octave_value_list retval;
  38.  
  39.   switch (nargout)
  40.     {
  41.     case 0:
  42.     case 1:
  43.       {
  44.     int count = i_idx.length ();
  45.     ColumnVector tmp (count);
  46.     for (int i = 0; i < count; i++)
  47.       tmp (i) = nr * (j_idx (i) - 1.0) + i_idx (i);
  48.  
  49.     // If the original argument was a row vector, force a row
  50.     // vector of indices to be returned.
  51.  
  52.     retval(0) = octave_value (tmp, (nr != 1));
  53.       }
  54.       break;
  55.  
  56.     case 3:
  57.       retval(2) = val;
  58.       // Fall through!
  59.  
  60.     case 2:
  61.       retval(1) = octave_value (j_idx, 1);
  62.       retval(0) = octave_value (i_idx, 1);
  63.  
  64.       // If you want this to work more like Matlab, use
  65.       //
  66.       //    retval(0) = octave_value (i_idx, (nr != 1));
  67.       //
  68.       // instead of the previous statement.
  69.  
  70.       break;
  71.  
  72.     default:
  73.       panic_impossible ();
  74.       break;
  75.     }
  76.  
  77.   return retval;
  78. }
  79.  
  80. static octave_value_list
  81. find_nonzero_elem_idx (const Matrix& m, int nargout)
  82. {
  83.   int count = 0;
  84.   int m_nr = m.rows ();
  85.   int m_nc = m.columns ();
  86.  
  87.   int i, j;
  88.   for (j = 0; j < m_nc; j++)
  89.     for (i = 0; i < m_nr; i++)
  90.       if (m (i, j) != 0.0)
  91.     count++;
  92.  
  93.   octave_value_list retval (((nargout == 0) ? 1 : nargout), Matrix ());
  94.  
  95.   if (count == 0)
  96.     return retval;
  97.  
  98.   ColumnVector i_idx (count);
  99.   ColumnVector j_idx (count);
  100.   ColumnVector v (count);
  101.  
  102.   count = 0;
  103.   for (j = 0; j < m_nc; j++)
  104.     for (i = 0; i < m_nr; i++)
  105.       {
  106.     double d = m (i, j);
  107.     if (d != 0.0)
  108.       {
  109.         i_idx (count) = i + 1;
  110.         j_idx (count) = j + 1;
  111.         v (count) = d;
  112.         count++;
  113.       }
  114.       }
  115.  
  116.   octave_value tmp (v, 1);
  117.   return find_to_fortran_idx (i_idx, j_idx, tmp, m_nr, nargout);
  118. }
  119.  
  120. static octave_value_list
  121. find_nonzero_elem_idx (const ComplexMatrix& m, int nargout)
  122. {
  123.   int count = 0;
  124.   int m_nr = m.rows ();
  125.   int m_nc = m.columns ();
  126.  
  127.   int i, j;
  128.   for (j = 0; j < m_nc; j++)
  129.     for (i = 0; i < m_nr; i++)
  130.       if (m (i, j) != 0.0)
  131.     count++;
  132.  
  133.   octave_value_list retval (((nargout == 0) ? 1 : nargout), Matrix ());
  134.  
  135.   if (count == 0)
  136.     return retval;
  137.  
  138.   ColumnVector i_idx (count);
  139.   ColumnVector j_idx (count);
  140.   ComplexColumnVector v (count);
  141.  
  142.   count = 0;
  143.   for (j = 0; j < m_nc; j++)
  144.     for (i = 0; i < m_nr; i++)
  145.       {
  146.     Complex c = m (i, j);
  147.     if (c != 0.0)
  148.       {
  149.         i_idx (count) = i + 1;
  150.         j_idx (count) = j + 1;
  151.         v (count) = c;
  152.         count++;
  153.       }
  154.       }
  155.  
  156.   octave_value tmp (v, 1);
  157.   return find_to_fortran_idx (i_idx, j_idx, tmp, m_nr, nargout);
  158. }
  159.  
  160. DEFUN_DLD (find, args, nargout,
  161.   "find (X) or [I, J, V] = find (X): Return indices of nonzero elements")
  162. {
  163.   octave_value_list retval;
  164.  
  165.   int nargin = args.length ();
  166.  
  167.   if (nargin != 1 || nargout > 3)
  168.     {
  169.       print_usage ("find");
  170.       return retval;
  171.     }
  172.  
  173.   octave_value arg = args(0);
  174.  
  175.   if (arg.is_real_type ())
  176.     {
  177.       Matrix m = arg.matrix_value ();
  178.  
  179.       if (! error_state)
  180.     retval = find_nonzero_elem_idx (m, nargout);
  181.     }
  182.   else if (arg.is_complex_type ())
  183.     {
  184.       ComplexMatrix m = arg.complex_matrix_value ();
  185.  
  186.       if (! error_state)
  187.     retval = find_nonzero_elem_idx (m, nargout);
  188.     }
  189.   else
  190.     {
  191.       gripe_wrong_type_arg ("find", arg);
  192.     }
  193.  
  194.   return retval;
  195. }
  196.  
  197. /*
  198. ;;; Local Variables: ***
  199. ;;; mode: C++ ***
  200. ;;; End: ***
  201. */
  202.